package com.example.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.bean.FileDemo;
import com.example.service.FileService;
import com.example.until.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @title: FileController
 * @Author wjf
 * @Date: 2022/9/25 11:45
 * @Version 1.0
 */
@RestController
@CrossOrigin
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FileService fileService;

    @Value("${files.upload.path}")
    private String fileUploadPath;

    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename(); //文件名
        String type = FileUtil.extName(originalFilename);  //文件类型
        long size = file.getSize();    //文件大小
        //先存储到磁盘

        //定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        String fileUUID = uuid + StrUtil.DOT + type;   // StrUtil.DOT 相当于 .
        File uploadFile = new File(fileUploadPath + fileUUID);
        //判断配置的文件目录是否存在,若不存在则创建一个新的目录

        File parentFile = uploadFile.getParentFile();    //File file1 = new File(fileUploadPath);
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }

        String url = null;
        String md5;
        //上传文件到磁盘
        file.transferTo(uploadFile);
        //获取文件的md5
        md5 = SecureUtil.md5(uploadFile);
        //从数据库中查询是否存在相同的记录
        FileDemo dbFiles = getFileByMd5(md5);
        if (dbFiles != null) {
            url = dbFiles.getUrl();
            //由于文件已存在，所有删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据库若不存在，则不删除刚才上传的文件
            url = "http://localhost:9090/file/" + fileUUID;
        }

        //存储到数据库
        FileDemo fileDemo = new FileDemo();
        fileDemo.setName(originalFilename);
        fileDemo.setType(type);
        fileDemo.setSize(size / 1024);
        fileDemo.setUrl(url);
        fileDemo.setMd5(md5);
        fileService.save(fileDemo);
        return url;
    }

    @GetMapping("/{fileUUID}")
    public void downLoad(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        //根据文件的唯一标识获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        //设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");

        //读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }

    /**
     * 根据md5查询数据
     *
     * @param md5
     * @return
     */
    public FileDemo getFileByMd5(String md5) {
        QueryWrapper<FileDemo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<FileDemo> list = fileService.list(queryWrapper);
        return list.size() == 0 ? null : list.get(0);
    }

    /**
     * 根据条件分页查询
     *
     * @param current
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public Result<IPage<FileDemo>> getFilePage(
            @RequestParam(defaultValue = "1") Integer current,
            @RequestParam(defaultValue = "5") Integer pageSize,
            @RequestParam String name) {
        IPage<FileDemo> fileDemoIPage = new Page<>(current, pageSize);
        QueryWrapper<FileDemo> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(name), "name", name);
        IPage<FileDemo> page = fileService.page(fileDemoIPage, queryWrapper);
        return Result.ok(page);
    }

    @DeleteMapping("/del/{id}")
    public Result delFileById(@PathVariable Integer id) {
        boolean b = fileService.removeById(id);
        return Result.ok(b);
    }

    @DeleteMapping("/del/batch/{ids}")
    @CrossOrigin
    public Result delByBatch(@PathVariable List<Integer> ids) {
        boolean b = fileService.removeBatchByIds(ids);
        return Result.ok(b);
    }

    @PutMapping("/update")
    public Result upDate(@RequestBody FileDemo fileDemo) {
        boolean b = fileService.updateById(fileDemo);
        return Result.ok(b);
    }

    @GetMapping("/video/findAll")
    public Result findAll(){
        List<FileDemo> list = fileService.list();
        return Result.ok(list);
    }

    @GetMapping("/video/{id}")
    public Result find(@PathVariable Integer id){
        FileDemo byId = fileService.getById(id);
        return Result.ok(byId);
    }
}
